package com.share.device.emqx.factory.impl;

import com.share.device.emqx.annotation.YEmqx;
import com.share.device.emqx.factory.MessageHandlerFactory;
import com.share.device.emqx.handler.MessageHandler;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

@Service
public class MessageHandlerFactoryImpl implements MessageHandlerFactory, ApplicationContextAware {

    //键为topic，值为对应的handler
    private Map<String, MessageHandler> handlerMap = new HashMap<>();


    //获取到所有业务的handler，并放入map中
    //参数是ioc容器，可以获取其中bean
    @Override
    public void setApplicationContext(ApplicationContext ioc) {
        //从ioc中获取handler实现类bean
        Map<String, MessageHandler> messageHandlerMap = ioc.getBeansOfType(MessageHandler.class);

        //遍历所有的值：所有的handler，放入handlerMap中
        for (MessageHandler messageHandler : messageHandlerMap.values()) {
            //使用工具类获取handler的所有 YEmqx注解对象 参数：目标对象类型，注解类型
            //set集合只有一个YEmqx注解对象
//            Set<YEmqx> allMergedAnnotations = AnnotatedElementUtils.findAllMergedAnnotations(messageHandler.getClass(), YEmqx.class);
            //通过迭代器 从set集合中获取到 YEmqx 对象
//            Iterator<YEmqx> iterator = allMergedAnnotations.iterator();
//            YEmqx yEmqx = iterator.next();

            YEmqx yEmqx = AnnotatedElementUtils.findAllMergedAnnotations(messageHandler.getClass(), YEmqx.class).iterator().next();

            //保证获取到了注解对象
            if (yEmqx != null) {
                String topic = yEmqx.topic();//获取topic
                // 放入map key：topic    value:对应handler
                handlerMap.put(topic, messageHandler);
            }
        }
    }

    //从handlerMap中获取对应topic的handler
    @Override
    public MessageHandler getMassageHandler(String topic) {
        return handlerMap.get(topic);
    }

}
